﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;
using System.Drawing;
using System.IO;

namespace Zampolit
{
    class FileManager
    {
        /// <summary>
        /// Директория в которой находится менеджер
        /// </summary>
        public string NowDirectory { get; set; }

        /// <summary>
        /// история перемещений
        /// </summary>
        public Stack<string> History { get; private set; }

        private FileManager()
        {
        }

        public FileManager(string directory)
        {
            History = new Stack<string>();
            ScanDir(directory);

        }

        public List<DirectoryInfo> _Directories;
        public List<FileInfo> _Files;


        void ScanDir(string directory)
        {
            DirectoryInfo dinfo = new DirectoryInfo(directory);

            _Files = new List<FileInfo>(dinfo.GetFiles());
            _Directories = new List<DirectoryInfo>(dinfo.GetDirectories());

            NowDirectory = directory;
            History.Push(NowDirectory);
        }


        /// <summary>
        /// открывает файл или директорию папки в которой находится
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        public bool Open(string FullPath)
        {
            bool d = Directory.Exists(FullPath);
            bool f = File.Exists(FullPath);

            if (d)
            {
                ScanDir(FullPath);
                return true;
            }

            if (f)
            {

                System.Diagnostics.Process.Start(FullPath);
                return true;
            }

            return false;
        }

        /// <summary>
        /// выдает имена файлов и папок в директории
        /// </summary>
        public List<string> Files
        {
            get
            {
                List<string> A = new List<string>();

                for (int i = 0; i < _Files.Count; i++)
                    A.Add(_Files[i].Name);

                for (int i = 0; i < _Directories.Count; i++)
                    A.Add(_Directories[i].Name);

                return A;
            }
        }

        public bool GoBack()
        {
            if (History.Count == 0)
                return false;

            History.Pop();
            ScanDir(History.Pop());

            return true;
        }


        public void Serch(string SerchText, string ParentDir)
        {
            List<object> L = Recurse_Serch(new DirectoryInfo(ParentDir), ref SerchText);

            _Files = new List<FileInfo>();
            _Directories = new List<DirectoryInfo>();

            NowDirectory = "";

            foreach (object O in L)
                if (O is FileInfo) _Files.Add((FileInfo)O);
                else _Directories.Add((DirectoryInfo)O);
        }

        List<object> Recurse_Serch(DirectoryInfo dir, ref string SerchText)
        {
            List<object> Result = new List<object>();

            DirectoryInfo[] DirectMass;
            try { DirectMass = dir.GetDirectories(); }
            catch { DirectMass = new DirectoryInfo[0]; }

            foreach (DirectoryInfo D in DirectMass)
            {
                if (D.Name.Contains(SerchText)) Result.Add(D);
                Result.AddRange(Recurse_Serch(D, ref SerchText));
            }

            FileInfo[] FileMass;
            try { FileMass = dir.GetFiles(); }
            catch { FileMass = new FileInfo[0]; }

            foreach (FileInfo F in FileMass)
                if (F.Name.Contains(SerchText))
                    Result.Add(F);

            return Result;
        }
    }

    class FileViewer
    {
        public ListView L_View;
        FileManager F_Manager;

        private FileViewer()
        { 
        }

        public FileViewer(Control Owner, string baseDir)
        {
            L_View = new ListView();
            L_View.SelectedIndexChanged += L_View_SelectedIndexChanged;

            L_View.MouseUp += listView1_MouseUp;


            L_View.Width = 435;
            L_View.Height = 500;
            L_View.Parent = Owner;

            L_View.View = View.List;



            F_Manager = new FileManager(baseDir);
            Show();
        }

        void Show()
        {
            L_View.Items.Clear();
            ImageList C = new ImageList();
            L_View.LargeImageList = C;
            L_View.SmallImageList = C;

            if (F_Manager.History.Count > 1)
            {
                C.Images.Add(Image.FromFile("4.png"));
                L_View.Items.Add(new ListViewItem("<-..", C.Images.Count - 1)); 
            }

            for (int i = 0; i < F_Manager.Files.Count; i++)
            {
                System.Drawing.Icon ic;
                try
                {
                    ic = System.Drawing.Icon.ExtractAssociatedIcon(F_Manager.NowDirectory + "\\" + F_Manager.Files[i]);
                    C.Images.Add(ic);
                    L_View.Items.Add(new ListViewItem(F_Manager.Files[i], C.Images.Count - 1));  
                }
                catch
                {
                    try
                    {
                        C.Images.Add(Image.FromFile("4.png"));
                        L_View.Items.Add(new ListViewItem(F_Manager.Files[i], C.Images.Count - 1));
                    }
                    catch
                    {
                    }
                }
            }
        }

        private void listView1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
                if (F_Manager.NowDirectory != "")
                    System.Diagnostics.Process.Start(F_Manager.NowDirectory);
        }

        private void L_View_SelectedIndexChanged(object sender, EventArgs e)
        {
            int delta;

            if (F_Manager.History.Count != 1)
                delta = 1;
            else
                delta = 0;
                    

            if (L_View.SelectedItems.Count == 1)
            {
                if (L_View.SelectedItems[0].Text == "<-..")
                    F_Manager.GoBack(); 
                else
                    if (L_View.SelectedItems[0].Index < F_Manager._Files.Count + delta)
                        F_Manager.Open(F_Manager._Files[L_View.SelectedItems[0].Index - 1].FullName);
                    else
                        F_Manager.Open(F_Manager._Directories[L_View.SelectedItems[0].Index - F_Manager._Files.Count - delta].FullName);
                    Show();
            }
        }

        public void Serch(string SerchText, string ParentDir)
        {
            F_Manager.Serch(SerchText, ParentDir);
            Show();        
        }
        
    }
}
